package dao

import (
	"context"
	"sale-admin/internal/dal"
	"sale-admin/internal/define"
	"sale-admin/internal/models"
	"strings"

	"192.168.1.75/go-pkg/errorx"
)

type ObjAssociation struct{}

// Add 添加关联关系
// objID 对象id
// associationID 关联对象id
func (o ObjAssociation) Add(
	ctx context.Context,
	query *dal.Query,
	records []*models.MaObjAssociation,
	batchSize int,
) (
	[]string, // 绑定成功的ids
	error,
) {
	oj := query.MaObjAssociation
	err := oj.WithContext(ctx).CreateInBatches(records, batchSize)
	if err != nil {
		return []string{}, errorx.New("关联关系创建失败", -1)
	}
	ids := []string{}
	for _, record := range records {
		ids = append(ids, record.ID)
	}
	return ids, nil
}

// Delete 删除关联关系
// objID 对象id
// associationID 关联对象id
func (o ObjAssociation) Delete(ctx context.Context, query *dal.Query, associationType define.AssociationType, objID, associationID string) error {
	if objID == "" && associationID == "" {
		return errorx.New("关联条件不能为空", -1)
	}
	oj := query.MaObjAssociation
	tx := oj.WithContext(ctx)
	tx = tx.Where(oj.AssociationType.Eq(int(associationType)))
	if objID != "" {
		tx = tx.Where(oj.ObjID.Eq(objID))
	}
	if associationID != "" {
		tx = tx.Where(oj.AssociationID.Eq(associationID))
	}
	_, err := tx.Delete(&models.MaObjAssociation{})
	if err != nil {
		return errorx.New("删除关联关系失败", -1)
	}
	return nil
}

// GetAssociationID 获取关联id
func (o ObjAssociation) GetAssociationID(
	ctx context.Context,
	query *dal.Query,
	associationType define.AssociationType, // 关联类型
	objID string, //对象id
	associationID string, // 关联对象id
) ([]string, error) {
	var ids []string
	oj := query.MaObjAssociation
	tx := oj.WithContext(ctx).Where(oj.AssociationType.Eq(int(associationType)))
	if objID == "" && associationID == "" {
		return []string{}, errorx.New("对象id不能为空", -1)
	}
	if objID != "" {
		tx = tx.Where(oj.ObjID.In(strings.Split(objID, ",")...))
		records, _ := tx.Select(oj.AssociationID).Order(oj.CreatedAt.Desc()).Find()
		for _, record := range records {
			ids = append(ids, record.AssociationID)
		}
		return ids, nil
	} else if associationID != "" {
		tx = tx.Where(oj.AssociationID.In(strings.Split(associationID, ",")...))
		records, _ := tx.Select(oj.ObjID).Order(oj.CreatedAt.Desc()).Find()
		for _, record := range records {
			ids = append(ids, record.ObjID)
		}
		return ids, nil
	}
	return []string{}, nil
}

// ExistAssociation 是否存在关联
// 参数（对象和关联对象）必须
func (o ObjAssociation) ExistAssociation(
	ctx context.Context,
	query *dal.Query,
	associationType define.AssociationType, // 关联类型
	objID, associationID string,
) bool {
	oj := query.MaObjAssociation
	count, err := oj.WithContext(ctx).
		Where(oj.AssociationType.Eq(int(associationType))).
		Where(oj.ObjID.Eq(objID)).
		Where(oj.AssociationID.Eq(associationID)).
		Count()
	if err == nil && count == 1 {
		return true
	}
	return false
}

// Exists 是否存在记录
// 对象或关联对象二选一，也就是是否存在相关的记录
func (o ObjAssociation) Exists(
	ctx context.Context,
	query *dal.Query,
	objID, associationID string,
) bool {
	oj := query.MaObjAssociation
	count, err := oj.WithContext(ctx).
		Where(oj.ObjID.Eq(objID)).
		Or(oj.AssociationID.Eq(associationID)).
		Count()
	if err == nil && count >= 1 {
		return true
	}
	return false
}
